package com.by.service.impl;

import com.by.entity.Minio;
import com.by.service.MinioService;
import io.minio.*;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

@Service
public class MinioServiceImpl implements MinioService {
    @Autowired
    MinioClient minioClient;
    @Autowired
    Minio minio;
    //1.上传
    public String upload(String bucketName, MultipartFile file) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            //如果桶不存在，创建桶
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            //获取时间
            String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            //UUID
            String uuid = UUID.randomUUID().toString();
            //获取文件名
            String originalFilename = file.getOriginalFilename();
            String extension =originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = uuid + extension;
            String fileName = dateTime + "/" + newFileName;
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
            String url = minio.getUrl() + "/" + bucketName + "/" + fileName;
            return url;

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件上传失败");
        }

    }
    /*我们虽然能够上传文件，并返回了文件在Minio中的地址，但是我们现在并不能直接去访问，因为现在这个桶test默认的访问权限不够，我们要在Minio的客户端将这个桶的访问权限设为public。创建存储桶时无法直接设置为公开访问，你需要在创建存储桶后再设置存储桶的策略来实现公开访问。这是因为MinIO遵循最小权限原则，以确保数据安全。*/


    //2.下载
    public ResponseEntity<InputStreamResource> download(String url){
        String objectUrl = url.split(minio.getBucketName() + "/")[1];
        InputStream inputStream = null;
        try {
            inputStream = minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(minio.getBucketName())
                            .object(objectUrl)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件下载失败");
        }
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + url + "\"")
                .body(new InputStreamResource(inputStream));
    }

    //3.删除
    public String delete(String url) {
        String objectUrl = url.split(minio.getBucketName() + "/")[1];
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(minio.getBucketName())
                    .object(objectUrl)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("文件删除失败");
        }
        return "文件删除成功";
    }
}
